Developer Documentation

QuickTime 4 API Documentation

3D Graphics Programming with QuickDraw 3D 1.5.4

Previous | QD3D Book | Overview | Chapter Contents | Next |

Creating a Model

As explained in "Modeling and Rendering" , creating an image of a three-dimensional model involves several steps. You must first create a model and then specify key information about the scene (such as the lighting and camera angle). This section shows how to create a simple model containing three-dimensional objects.

Objects in QuickDraw 3D are defined using a Cartesian coordinate system that is right-handed (that is, if the thumb of the right hand points in the direction of the positive x axis and the index finger points in the direction of the positive y axis, then the middle finger, when made perpendicular to the other two fingers, points in the direction of the positive z axis). Figure 5 shows a right-handed coordinate system.

For a more complete description of the coordinate spaces used by QuickDraw 3D, see the chapter "Transform Objects" later in this book.

Figure 5 A right-handed Cartesian coordinate system

The model created by the MyNewModel function defined in Listing 4 consists of a number of boxes that spell out the words "Hello World." The words are written in block letters, with each letter composed of a number of individual boxes. MyNewModel uses the inelegant but straightforward method of defining the 34 boxes by creating four arrays of 34 elements each. As described in the chapter "Geometric Objects" , a box is defined by four pieces of information, an origin and three vectors that specify its sides:

typedef struct TQ3BoxData {
    TQ3Point3D                          origin;
    TQ3Vector3D                         orientation;
    TQ3Vector3D                         majorAxis;
    TQ3Vector3D                         minorAxis;
    TQ3AttributeSet                     *faceAttributeSet;
    TQ3AttributeSet                     boxAttributeSet;
} TQ3BoxData;

First, MyNewModel creates a new and empty ordered display group to contain all the boxes. Then the function loops through the data arrays, creating boxes and adding them to the group.

Listing 4 Creating a model

TQ3GroupObject MyNewModel (void)
{
    TQ3GroupObject                  myModel;
    TQ3GeometryObject               myBox;
    TQ3BoxData                      myBoxData;
    TQ3GroupPosition                myGroupPosition;
    
    /*Data for boxes comprising Hello and World block letters.*/
    long        i;
    float       xorigin[34] = {
                    -12.0, -9.0, -11.0, -7.0, -6.0, -6.0, -6.0, -2.0, -1.0,
                    3.0, 4.0, 8.0, 9.0, 9.0, 11.0, -13.0, -12.0, -11.0, -9.0,
                    -7.0, -6.0, -6.0, -4.0, -2.0, -1.0, -1.0, 1.0, 1.0, 3.0,
                    4.0, 8.0, 9.0, 9.0, 11.0};
    float       yorigin[34] = {
                    0.0, 0.0, 3.0, 0.0, 6.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                    6.0, 0.0, 0.0, -8.0, -8.0, -7.0, -8.0, -8.0, -8.0, -2.0,
                    -8.0, -8.0, -2.0, -5.0, -4.0, -8.0, -8.0, -8.0, -8.0, -8.0,
                    -2.0, -7.0};
    float       height[34] = {
                    7.0, 7.0, 1.0, 7.0, 1.0, 1.0, 1.0, 7.0, 1.0, 7.0, 1.0, 7.0,
                    1.0, 1.0, 7.0, 7.0, 1.0, 3.0, 7.0, 7.0, 1.0, 1.0, 7.0, 7.0,
                    1.0, 1.0, 2.0, 3.0, 7.0, 1.0, 7.0, 1.0, 1.0, 5.0};
    float       width[34] = {
                    1.0, 1.0, 2.0, 1.0, 3.0, 2.0, 3.0, 1.0, 3.0, 1.0, 3.0, 1.0,
                    2.0, 2.0, 1.0, 1.0, 3.0, 1.0, 1.0, 1.0, 2.0, 2.0, 1.0, 1.0,
                    2.0, 2.0, 1.0, 1.0, 1.0, 3.0, 1.0, 2.0, 2.0, 1.0};
    /*Create an ordered display group for the complete model.*/
    myModel = Q3OrderedDisplayGroup_New();
    if (myModel == NULL)
        goto bail;

    /*Add all the boxes to the model.*/
    myBoxData.faceAttributeSet = NULL;
    myBoxData.boxAttributeSet = NULL;
    for (i=0; i<34; i++) {
        Q3Point3D_Set(&myBoxData.origin, xorigin[i], yorigin[i], 1.0);
        Q3Vector3D_Set(&myBoxData.orientation, 0, height[i], 0);
        Q3Vector3D_Set(&myBoxData.minorAxis, width[i], 0, 0);
        Q3Vector3D_Set(&myBoxData.majorAxis, 0, 0, 2);
        myBox = Q3Box_New(&myBoxData);
        myGroupPosition = Q3Group_AddObject(myModel, myBox);
        /*now that myBox has been added to group, dispose of our reference*/
        Q3Object_Dispose(myBox);
        if (myGroupPosition == NULL)
            goto bail;
    }

    return (myModel);                   /*return the completed model*/
    
bail:
    /*If any of the above failed, then return an empty model.*/
    return (NULL);
}

The MyNewModel function can leak memory. Your application should use a different error-recovery strategy than is used in Listing 4 .

If successful, MyNewModel returns the group object containing the 34 boxes to its caller.


© 1997 Apple Computer, Inc.

Previous | QD3D Book | Overview | Chapter Contents | Next |